package
{
	import com.greensock.TweenMax;
	import com.greensock.easing.Cubic;
	import com.ux.base.BLoader;
	import com.ux.base.BUrlLoader;
	
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.system.Security;
	import flash.utils.Timer;
	
	public class RollingGallery extends Sprite
	{
		
		//-----------------------------------------------------------------------------------
		//
		// private vars
		//
		//-----------------------------------------------------------------------------------
		
		private var _xmlPath : String = "xml/img.xml";
		private var _ldr : BUrlLoader;
		private var _clipList : Array;
		private var _selectedIndex : int = 0;
		private var _viewNum : int = 5; // 화면에 보여줄 갯수 ( 홀수여야 함 )
		private var _gap : Number = 110; // 이미지들의 간격.
		private var _rotationSize : Number = 80; // 회전 반경 ( y 축으로 )
		private var _zSize : Number = 100; // z sorting num
		private var _isAutoTimer : Boolean = true;
		private var _timer : Timer; 
		private var _delay : Number = 4000; // 타이머 간격
		
		
		//-----------------------------------------------------------------------------------
		//
		// constructor
		//
		//-----------------------------------------------------------------------------------
		
		public function RollingGallery()
		{
			this.addEventListener(Event.ADDED_TO_STAGE, onStage );
		}
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// setter, getter
		//
		//-----------------------------------------------------------------------------------
		public function get isAutoTimer():Boolean
		{
			return _isAutoTimer;
		}

		public function set isAutoTimer(value:Boolean):void
		{
			_isAutoTimer = value;
		}

		
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// private
		//
		//-----------------------------------------------------------------------------------
		
		private function onXmlLoadHandler():void
		{
			_clipList = [];
			var clip : ImgClip;
			var xml : XML = XML( _ldr.loadData );
			
			var len:int = xml.children().length();
			for (var i:int = 0; i < len; i++) 
			{
				clip = new ImgClip();
				clip.loadImg( xml.children()[ i ].@url );
				clip.linkUrl = xml.children()[ i ].@link;
				clip.target = xml.children()[ i ].@target;
				clip.x = stage.stageWidth/2;
				clip.y = stage.stageHeight/2;
				clip.addEventListener(MouseEvent.CLICK, onClipClick );
				clip.buttonMode = true;
				
				addChild( clip );
				_clipList.push( clip );
			}
			
			selectionControl();
			if( isAutoTimer )
			{
				_timer = new Timer( _delay, 0 );
				_timer.addEventListener(TimerEvent.TIMER, onTimer );
				_timer.start();
			}
		}
		
		/**
		 * 인덱스에따라 아이템 배치하는 키메서드 
		 */		
		private function selectionControl():void
		{
			
			var clipX : Number = 0;
			var clipY : Number = 0;
			var clipZ : Number = 0;
			var clipRotationY : Number = 0;
			
			var clip : ImgClip;
			var selectedClip : ImgClip;
			// 1. 선택된 인덱스의 클립을 중앙에 배치하고, 
			selectedClip = _clipList[ _selectedIndex ] as ImgClip;
			clipX = stage.stageWidth / 2;
			clipY = stage.stageHeight / 2;
			clipZ = 0;
			clipRotationY = 0;
			tweenClip( selectedClip, clipX, clipY, clipZ, clipRotationY );
			
			setChildIndex( selectedClip, numChildren - 1 );
			selectedClip.ON();
			
			var viewSideNum : Number = (_viewNum-1)/2; // 화면에 보여줄 양쪽 이미지 갯수 ( _viewNum-가운데 )/좌우 + 없어지는모션을 위한 1개 더.
			var sideNum : Number = Math.ceil( (_clipList.length)/2 ); // 가운데 이미지를 제외한 양쪽 이미지의 갯수. 
			var defaultGapBetweenCenter : Number = ( selectedClip.width*0.45 ); // 센터로부터 이격된 기본값.
			
			// 2. 오른쪽 리스트 정렬
			var i : int = 1;
			var len:int = sideNum+1;
			for ( i; i < len; i++) 
			{
				// 알파로 가려진것보다도 더 큰것은 연산하지 않는다.
				if( (i>viewSideNum+1) ) continue;
				
				clip = getClipAtIndex( +i );
				clipX = ( stage.stageWidth / 2 ) + defaultGapBetweenCenter + _gap*i;
				clipY = ( stage.stageHeight / 2 );
				clipZ = i*_zSize;
				clipRotationY = (_rotationSize+(_rotationSize*i*_zSize/800)); // _zSize/800 = z값에 따른 rotaionY 의변화를 일정하게 하기위해.
				tweenClip( clip, clipX, clipY, clipZ, clipRotationY, (i>viewSideNum)?0:1 );
				clip.OFF();
				setChildIndex( clip, getChildIndex(selectedClip)-i  );
			}
			
			
			// 3. 왼쪽 리스트 정렬
			len = _clipList.length-sideNum+1;
			i = 1;
			for ( i; i < len; i++) 
			{
				// 알파로 가려진것보다도 더 큰것은 연산하지 않는다.
				if( (i>viewSideNum+1) ) continue;
				
				clip = getClipAtIndex( -i );
				clipX = ( stage.stageWidth / 2 ) - defaultGapBetweenCenter - _gap*i;
				clipY = ( stage.stageHeight / 2 );
				clipZ = i*_zSize;
				clipRotationY = -(_rotationSize+(_rotationSize*i*_zSize/800));// _zSize/800 = z값에 따른 rotaionY 의변화를 일정하게 하기위해.
				tweenClip( clip, clipX, clipY, clipZ, clipRotationY, (i>viewSideNum)?0:1);
				
				clip.OFF();
				setChildIndex( clip, getChildIndex(selectedClip)-i  );
			}
			
		}
		
		
		/**
		 * @param compareCenterNum 
		 * @return 센터를 기준으로 좌우측으로 비교되는 인덱스의 클립 반환. 
		 * 
		 */		
		private function getClipAtIndex( compareCenterNum : Number ):ImgClip
		{
			var idx : Number = _selectedIndex + compareCenterNum;
			var len : Number = _clipList.length;
			
			if( idx >= len )
			{
				idx = idx - len;
			}
			else if( idx < 0 )
			{
				idx = idx + len;
			}
			
			return _clipList[ idx ] as ImgClip;
		}
		
		
		private function tweenClip( clip:ImgClip, x:Number, y:Number, z:Number, rotationY : Number, autoAlpha:Number=1 ):void
		{
			TweenMax.to( clip, 0.5, {x:x,y:y,z:z,rotationY:rotationY,autoAlpha:autoAlpha, ease:Cubic.easeOut} );
		}
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// event handler
		//
		//-----------------------------------------------------------------------------------
		
		
		protected function onStage(e:Event):void
		{
			e.currentTarget.removeEventListener( e.type, arguments.callee, !e.bubbles );
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			Security.allowDomain( "*" );
			
			if( stage.loaderInfo.parameters && stage.loaderInfo.parameters.xmlPath )
			{
				_xmlPath = stage.loaderInfo.parameters.xmlPath;
			}
			
			trace(" ==> RollingGallery onStage : " + _xmlPath );
			
			_ldr = new BUrlLoader( _xmlPath, onXmlLoadHandler );
			
		}
		
		
		protected function onTimer(e:TimerEvent):void
		{
			_selectedIndex = ( _selectedIndex + 1 >= _clipList.length ) ? 0 : _selectedIndex + 1;
			selectionControl();
		}		
		
		protected function onClipClick(e:MouseEvent):void
		{
			if( _timer )
			{
				_timer.reset();
				_timer.start();
			}
			_selectedIndex = _clipList.indexOf( e.currentTarget as ImgClip );
			selectionControl();
		}
		
			
	}
}